package com.apes.fn.server.vehicleFile.server.vehicleFileUploadProcess;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.fn.scm.retailOrder.model.RetailOrder;
import com.apes.fn.scm.retailOrder.model.RetailOrderItem;
import com.apes.fn.scm.retailOrder.repository.RetailOrderRepository;
import com.apes.fn.server.pickUpCar.model.PickUpCar;
import com.apes.fn.server.pickUpCar.repository.PickUpCarRepository;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.fn.server.transferVehicle.model.InnerPickDeliveryUpCar;
import com.apes.fn.server.transferVehicle.repository.InnerPickDeliveryUpCarRepository;
import com.apes.fn.server.vehicleFile.model.*;
import com.apes.fn.server.workOrder.model.MaintenanceOrder;
import com.apes.fn.server.workOrder.repository.MaintenanceOrderDao;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.esb.processor.connector.http.HttpTransporter;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.car.model.CarConfiguration;
import com.apes.scm.masterdata.car.repository.CarConfigurationRepository;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.model.ProductServiceHours;
import com.apes.scm.masterdata.product.repository.ProductServiceHoursRepository;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: apes-server
 * @description: 以云南为例
 * @author: czs
 * @create: 2023-11-02 14:56
 **/
public abstract class CommonUploadProcess extends DomainService implements VehicleFileUploadProcess {

    @Autowired
    private PickUpCarRepository pickUpCarRepository;
    @Autowired
    private MaintenanceOrderDao maintenanceOrderDao;

    @Override
    public String getToken(VehicleFileAccount vehicleFileAccount){
        VehicleFileArea vehicleFileArea = vehicleFileAccount.getVehicleFileArea();
        VehicleFileAreaItem tokenApi = vehicleFileArea.findItemByApiType("token");
        String interfaceData = interfaceData(tokenApi.getApiAddress(), getTokenMap(vehicleFileAccount));
        JSONObject token = JSONObject.parseObject(interfaceData);
        if (!token.getString("code").equals("1")) {
            throw new RuntimeException(token.getString("status"));
        }
        return token.getString("access_token");
    }
    public Map getTokenMap(VehicleFileAccount vehicleFileAccount){
        return MapUtil.mapper("companycode", vehicleFileAccount.getAccount(), "companypassword", vehicleFileAccount.getPassword());
    }

    @Override
    public boolean upload(VehicleFileAccount vehicleFileAccount, VehicleFileUploadInfo vehicleFileUploadInfo) {
        checkTokenValid(vehicleFileAccount);
        Map<String, Object> paket = paket(vehicleFileAccount, vehicleFileUploadInfo);
        String url = vehicleFileAccount.getVehicleFileArea().findItemByApiType("upload").getApiAddress();
        String interfaceData = interfaceData(url, paket);
        JSONObject req = JSONObject.parseObject(interfaceData);
        if (!req.getString("code").equals("1")) {
            throw new RuntimeException(req.getString("status"));
        }
        return true;
    }

    @Override
    public void checkTokenValid(VehicleFileAccount vehicleFileAccount) {
        Date date = new Date();
        if (vehicleFileAccount.getTokenStartDate()==null) {
            vehicleFileAccount.setToken(getToken(vehicleFileAccount));
            vehicleFileAccount.setTokenStartDate(date);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DATE,3);
            vehicleFileAccount.setTokenEndDate(calendar.getTime());
        }else if (date.after(vehicleFileAccount.getTokenEndDate())){
            vehicleFileAccount.setToken(getToken(vehicleFileAccount));
            vehicleFileAccount.setTokenStartDate(date);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DATE,3);
            vehicleFileAccount.setTokenEndDate(calendar.getTime());
        }
    }

    @Override
    public Map<String, Object> paket(VehicleFileAccount vehicleFileAccount,VehicleFileUploadInfo vehicleFileUploadInfo) {
        String token = vehicleFileAccount.getToken();
        RetailOrder retailOrder = findRetailOrder(vehicleFileUploadInfo);
        Map<String, Object> result = new HashMap();
        result.put("access_token",token);
        Map basicInfo = new HashMap();
        //维修工时
        List<Map> repairProjectList = new ArrayList<>();
        //维修配件
        List<Map> vehiclePartsList = new ArrayList<>();

        FnCustomerExpand fnCustomerExpand = vehicleFileUploadInfo.getFnCustomerExpand();
        PickUpCar pickUpCar = getPickUpCar(retailOrder,fnCustomerExpand);
        basicInfo.put("vehicleplatenumber",vehicleFileUploadInfo.getCarLicense());
        basicInfo.put("companyname",vehicleFileAccount.getFixCompanyName());
        basicInfo.put("vin", fnCustomerExpand.getVin());


        basicInfo.put("settledate", DateUtil.format(vehicleFileUploadInfo.getReceivableDate(),DateUtil.SHOW_DATE_NUMBER_FORMAT));//结算日期
        basicInfo.put("repairdate", DateUtil.format(vehicleFileUploadInfo.getFnCustomerExpand().getCreateDate(),DateUtil.SHOW_DATE_NUMBER_FORMAT));//送修日期
        basicInfo.put("repairmileage",pickUpCar.getMileage());//送修里程
        basicInfo.put("costlistcode",vehicleFileUploadInfo.getOrderId());//结算清单
        basicInfo.put("faultdescription",pickUpCar.getFaultDescription()==null?"无":pickUpCar.getFaultDescription());//故障描述
        String jekunModelCode = pickUpCar.getFnCustomerExpand().getJekunModelCode();
        CarConfiguration carConfiguration = SpringManager.getBean(CarConfigurationRepository.class).findOne(jekunModelCode);
//        if (carConfiguration==null)throw new RuntimeException("车型不存在:"+jekunModelCode);
        basicInfo.put("fueltype",carConfiguration==null?"无":VehicleFileFuelTypeEnum.JekunFuelTypeChange(carConfiguration.getFuelType()).getCode());//燃油类型

        String str = this.invoke("pi.app.ext", MapUtil.mapper("headers",MapUtil.mapper("method","v1/vehicle-license/use-for-label",
                "action","get"),"body",MapUtil.mapper("carLicense",vehicleFileUploadInfo.getCarLicense())));
        JSONObject jsonObject = JSONObject.parseObject(str);
        String useForLabel = jsonObject.getJSONObject("data").getString("useForLabel");
        String vehicleusecharacter = useForLabel.equals("") ?
                "无" : useForLabel.equals("营运")?"01":"02"
                ;
        basicInfo.put("vehicleusecharacter", vehicleusecharacter);//车辆使用性质


        String serveTypes = vehicleFileUploadInfo.getServeTypes();
        List uploadType = new ArrayList();
        String[] split = serveTypes.split(";");
        for (String s : split) {
            String[] xes = s.split("X");
            if (xes.length>0){
                uploadType.add(xes[0]);
            }
        }

        retailOrder.getSaleItems().stream()
                .filter(retailOrderItem -> uploadType.contains(retailOrderItem.getProduct().getClassify().getName()))
                .forEach(retailOrderItem -> {
                    Product product = retailOrderItem.getProduct();
                    Map productMap = new HashMap();
                    if ("10".equals(product.getProductGroup().getId())){
                        //配件
                        productMap.put("partsname",product.getName());//配件名称
                        productMap.put("partscode",product.getId());//配件编码
                        productMap.put("partsquantity",String.valueOf(retailOrderItem.getProductUomQty()));//配件数量
                        vehiclePartsList.add(productMap);
                    }else {
//                        ProductServiceHours productServiceHours = SpringManager.getBean(ProductServiceHoursRepository.class).findAll(JpaDsl.toCriteria("product", "EQ", product)).stream().findFirst().orElse(null);
//                        String workinghours = productServiceHours ==null?"0":String.valueOf(productServiceHours.getServiceHours()/60);
                        String workinghours = "0";
                        if (retailOrderItem.getOriginnumber()!=null){
                            JSONArray jsonArray = maintenanceOrderDao.queryProductHour(new JSONObject(MapUtil.mapper("plan_item_id", retailOrderItem.getOriginnumber())));
                            if (!jsonArray.isEmpty()){
                                JSONObject j = (JSONObject) jsonArray.get(0);
                                workinghours = j.getString("WORKHOUR");
                            }
                        }
                        productMap.put("repairproject",product.getName());//维修项目
                        productMap.put("workinghours",workinghours);//维修工时
                        repairProjectList.add(productMap);
                    }
                });
        result.put("basicInfo",basicInfo);
        result.put("repairprojectlist",repairProjectList);
        result.put("vehiclepartslist",vehiclePartsList);
        return result;
    }

    @Override
    public boolean register(VehicleFileAccount vehicleFileAccount) {
        return false;
    }

    private PickUpCar getPickUpCar(RetailOrder retailOrder,FnCustomerExpand fnCustomerExpand) {
        PickUpCar pickUpCar = null;
        //优先从方案获取
        if (retailOrder!=null){
            if (retailOrder.getSourceBusinessType().equals("ServicePlan")){
                ServicePlan servicePlan = SpringManager.getBean(ServicePlanRepository.class).findOne(retailOrder.getSource());
                if (servicePlan!=null&&servicePlan.getPickCarId()!=null){
                    if (servicePlan.getPickCarType().equals("PickUpCar")){
                        pickUpCar = pickUpCarRepository.findOne(servicePlan.getPickCarId());
                    }else {
                        InnerPickDeliveryUpCar innerPickDeliveryUpCar = SpringManager.getBean(InnerPickDeliveryUpCarRepository.class).findOne(servicePlan.getPickCarId());
                        Dept belongDept = innerPickDeliveryUpCar.getBelongDept();
                        pickUpCar = pickUpCarRepository.findByDeptIdAndFnCustomerExpandIdOrderByCreateDateDesc(belongDept.getId(), fnCustomerExpand.getId()).stream().max(Comparator.comparing(PickUpCar::getCreateDate)).orElse(null);
                    }
                }
            }
        }
        if (pickUpCar==null)
            pickUpCar = pickUpCarRepository.findAll(JpaDsl.toCriteria("fnCustomerExpand", "EQ", fnCustomerExpand)).stream().max(Comparator.comparing(PickUpCar::getCreateDate)).orElse(null);
        if (pickUpCar==null) {
            pickUpCar =pickUpCarRepository.findAll(JpaDsl.toCriteria("licenseNumber", "EQ", fnCustomerExpand.getCarLicense())).stream().max(Comparator.comparing(PickUpCar::getCreateDate)).orElse(null);
        }
        if (pickUpCar == null)throw new RuntimeException("没有找到对应接车单!请先接车");

        return pickUpCar;
    }

    /**
     *
     * @param url 地址
     * @param param 入参
     * @return
     */
    public String interfaceData(String url, Map<String, Object> param) {
        Map headers = new HashMap();
        headers.put("Content-Type", "application/json");
        HttpTransporter transporter = new HttpTransporter();
        transporter.setUrl(url);
        transporter.setHeaders(headers);
        SimpleRequest rqst = new SimpleRequest();
        rqst.setData(JSONObject.toJSONString(param));
        return (String) transporter.process(rqst);
    }

    public RetailOrder findRetailOrder(VehicleFileUploadInfo vehicleFileUploadInfo){
        if (RetailOrder.class.getSimpleName().equals(vehicleFileUploadInfo.getOrderType())){
            return SpringManager.getBean(RetailOrderRepository.class).findOne(vehicleFileUploadInfo.getOrderId());
        }
        return null;
    }


}
